﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StockFinder.Entities;

namespace StockFinder.ChartPatterns
{
    public class WeeklyFlatBaseChartPattern
    {
        private readonly decimal BASE_DEPTH = 0.15M;
        private readonly int WEEKLY_COUNT_THRESHOLD = 5;

        public WeeklyFlatBaseChartPattern() { }

        public WeeklyFlatBaseChartPattern(decimal baseDepth, int weeklyCountThreshold)
        {
            BASE_DEPTH = baseDepth;
            WEEKLY_COUNT_THRESHOLD = weeklyCountThreshold;
        }

        public WeeklyFlatBaseResult DoesFit(Symbol symbol)
        {
            WeeklyFlatBaseResult result = new WeeklyFlatBaseResult();

            result.Symbol = symbol;

            decimal latestWeeklyHigh = 0;
            decimal maximumHigh = 0;
            decimal maximumLow = 0;
            decimal depth = 0;
            int weekCount = 0;
            int baseLength = 0;

            //check we have (enough) prices
            if (symbol.WeeklyPrices != null && symbol.WeeklyPrices.Count > WEEKLY_COUNT_THRESHOLD)
            {
                //setup new data
                latestWeeklyHigh = symbol.WeeklyPrices[0].GetWeeklyHigh();
                maximumHigh = symbol.WeeklyPrices[0].GetWeeklyHigh();
                maximumLow = symbol.WeeklyPrices[0].GetWeeklyLow();

                //loop prices
                foreach (WeeklyPrice weeklyPrice in symbol.WeeklyPrices)
                {
                    //check not empty prices
                    if (weeklyPrice.GetWeeklyOpen() == 0)
                    {
                        break;
                    }

                    //new week
                    weekCount++;

                    //do we have a new peak?
                    if (weeklyPrice.GetWeeklyHigh() > maximumHigh)
                    {
                        //yes
                        maximumHigh = weeklyPrice.GetWeeklyHigh();
                    }

                    //do we have a new low point?
                    if (weeklyPrice.GetWeeklyLow() < maximumLow)
                    {
                        //yes
                        maximumLow = weeklyPrice.GetWeeklyLow();
                    }

                    //calculate depth
                    depth = (maximumHigh - maximumLow) / maximumHigh;

                    /* FLAT BASE CHECK */

                    //have we breached base depth?
                    if (depth > BASE_DEPTH)
                    {
                        //yes so check base length
                        result.DoesFit = (baseLength >= WEEKLY_COUNT_THRESHOLD);

                        //need to quit as depth breached
                        break;
                    }
                    else
                    {
                        //no so check if this week was a valid base start
                        if (weeklyPrice.GetWeeklyHigh() == maximumHigh)
                        {
                            //yes so determine new base length
                            baseLength = weekCount;
                        }
                    }                  
                }
            }

            result.BaseLength = baseLength;

            return result;
        }
    }
}
